Computer system with an improved device and driver framework

ABSTRACT

Each driver has a global driver section comprising drive program code and global driver data, both defining driver operations associated with a corresponding class of devices. Each device has an associated driver instantiation comprising local driver data, having an internal pointer to the global driver section of the instantiated driver, and possibly at least one external pointer to another driver instantiation. A device registry forms a list of device registry entries, each corresponding to a respective one of the drive instantiations. Driveer client code may perform operations on a given device by fetching in the device registry a pointer to the driver instantiation associated with the given device, and then use operations provided by the associated driver instantiation, directly or using further operations reached in other driver instantiations by using iteratively the external printer.

BACKGROUND OF THE INVENTION

[0001] This invention relates to computer technology.

[0002] Real time embedded operating systems are of increasing interestin various applications. An example is the operating system (OS) namedChorusOS (a product and trademark of SUN MICROSYSTEMS), which isflexible as to the hosting hardware. This means that it may have to beinstalled and configured on a variety of computer platforms.

[0003] For being installed on a particular machine (“target”), an OSlike ChorusOS has to be prepared in accordance with the targetcharacteristics, including its main board, the corresponding boardsupport package (BSP), and its specific drivers. Usually, the targetwill include additional devices, also with their own drivers.

SUMMARY OF THE INVENTION

[0004] Thus, in view of the desired flexibility, a number of differentdrivers may have to be loaded, depending upon the systems. The abilityto hot swapping a device is also desirable. Hot swap means maintainingthe system functions for the time interval extending from unplugging anexisting device to plugging in a new device in substitution of theunplugged existing device. In other words, hot swap includes both hotunplug and hot plug, and continue to play while maintaining systemfunctions in each case.

[0005] This invention intends to improve the driver and device frameworkin such a system.

[0006] Another object of this invention is to provide a very scalableway to configure/initialize a set of device drivers to operate ahardware platform.

[0007] Another object of this invention is to provide a driver anddevice framework adapted to range from low memory footprint staticsoftware configurations, where a built-in driver is statically bound toeach supported device, to very large hardware and softwareconfigurations where the set of physical devices is not known a priori.

[0008] A further object of this invention is to enable devices to bedynamically added in/removed from the system, and/or to enable devicesto be dynamically probed.

[0009] Still another object of this invention is to enable thedownloading of drivers from the network.

[0010] The invention applies to a computer system comprising aprocessor, a memory, devices, and a program memory area, for storing anoperating system, drivers, and driver client code (applications).

[0011] Each driver has a global driver section comprising driver programcode and global driver data, both defining driver operations associatedwith a corresponding class of devices.

[0012] For each operative one of the devices, there is provided anassociated driver instance comprising local driver data. The local datamay have an internal pointer to the instantiated driver. They may alsohave at least one external pointer to another driver instance. The localdriver data may still further comprise local device data, defining acurrent condition of the associated device.

[0013] A device registry forms a list of device registry entries, eachcorresponding to a respective one of the driver instances. A driverclient code is thus capable of performing operations on a given deviceby:

[0014] fetching in the device registry a pointer to the driver instanceassociated with the given device,

[0015] performing the given device operations provided by the associateddriver instance, directly or using further operations reached in otherdriver instances by using iteratively said external pointer.

[0016] The invention may also be defined as a method of managingdrivers, or a driver framework, in a computer, comprising the steps of:

[0017] a. providing each driver with a global driver section comprisingdriver program code and global driver data, both defining driveroperations associated with a corresponding class of devices,

[0018] b. for each operative one of the devices, providing an associateddriver instantiation comprising local driver data, having an internalpointer to the instantiated driver,

[0019] c. providing a device registry, forming a list of device registryentries, each corresponding to a respective one of the driverinstantiations.

[0020] Thus, a device call may be directed to the device registry, toreach the driver instantiation corresponding to the device being called.

[0021] Preferably, provision is made for device tree data, defining atree representation of at least some of the devices. In the tree, eachdevice node represents a device and its device characteristics, andidentifies at most one driver capable of managing that device. Thedevice registry entry may further comprise a node identifier, definingan associated node in the device tree.

[0022] On another hand, the global driver section may comprise codeadapted to implement at least one of the following special operations,non limitatively: self-registering the driver in the driver registry,identifying devices the driver can serve, creating a node in the devicetree, binding a device with a driver, creating a new driver instance,unloading a driver.

[0023] According to another feature, there is provided for a driverregistry, forming a list of driver registry entries, each comprising atleast one pointer to the special operations. The driver registry maydirectly or indirectly define device-independent driver characteristics,comprising a driver identifier and a parent driver class identifier. Inparticular drivers, the global driver section may comprise code adaptedto explore the driver registry for finding drivers matching the class ofthe particular driver.

[0024] The invention also includes the software code portions beingused, including individual driver code, and portions of code in theoperating system, or in its nucleus, which implement the functionalitiesof this invention.

BRIEF DESCRIPTION OF THE DRAWINGS

[0025] Other features and advantages of the invention will appear in thedetailed description below and in the appended drawings, in which:

[0026]FIG. 1 schematically illustrates a hardware computer structure inwhich the invention may be practiced;

[0027]FIG. 2 schematically illustrates a device driver system for thehardware computer structure of FIG. 1;

[0028]FIG. 3 illustrates a device driver framework in accordance with anembodiment of the invention for the hardware computer structure of FIG.1;

[0029]FIG. 4 illustrates a device registry and a driver registry,cooperating with a global driver and an instantiation of that globaldriver;

[0030]FIG. 5 illustrates an exemplary device tree;

[0031]FIG. 6 illustrates a corresponding exemplary driver tree;

[0032]FIG. 7 is a flowchart illustrating a driver registration;

[0033]FIG. 8 is a flowchart illustrating the main steps of bus driverinitialization;

[0034]FIG. 9 is a flowchart illustrating step 910 of FIG. 8 in moredetail;

[0035]FIG. 10 is a flowchart illustrating step 920 of FIG. 8 in moredetail;

[0036]FIG. 11 is a flowchart illustrating step 930 of FIG. 8 in moredetail;

[0037]FIG. 12 is a flowchart illustrating the steps of leaf driverinitialization;

[0038]FIG. 13 is a flowchart illustrating the steps of processing a loadhandler;

[0039]FIG. 14 shows table T1, useful for the detailed description;

[0040]FIG. 15 shows table T2, useful for the detailed description;

[0041]FIG. 16 shows table T3, useful for the detailed description;

[0042]FIG. 17 shows table T4, useful for the detailed description;

[0043]FIG. 18 shows table T5, useful for the detailed description; and

[0044]FIG. 19 shows table T6, useful for the detailed description.

[0045] Additionally, the detailed description is supplemented withExhibits, in which:

[0046] Exhibit A contains pseudocode of various routines in C typelanguage; and

[0047] Exhibit B contains comments on the routines of Exhibit A, using acorresponding paragraph numbering.

[0048] The Figures and Exhibits include graphical and/or codeinformation, which may be useful to define the scope of this invention.

DETAILED DESCRIPTION

[0049] Making reference to software entities imposes certain conventionsin notation. For example, in the detailed description, the quote sign “may be used as a string delimiter wherever deemed necessary for clarity(e.g. “actor”). Square brackets may be used to frame the optionalportion of an expression (e.g. “[OS] archive”).

[0050] The detailed description hereinafter refers to platforms based onthe ChorusOS operating system, and uses the corresponding terminology.This is exemplary only and it should be understood that the invention isapplicable to a variety of computer platforms. Generally, Chorusos hasthe following abilities:

[0051] work with various processors and various main boards, adapted tospecific products;

[0052] be loadable in RAM from a so called “[OS] archive” or “imagefile”, stored e.g. in persistent memory or as a file on the hard disk,depending upon the actual platform architecture;

[0053] define independent processes (named “actors”), exchangingmessages.

[0054] The exemplary hardware computer structure of FIG. 1 comprises aCPU 110, having a CPU Bus 112, and RAM 115 connected thereto. A PCI BusBridge 118 is interposed between CPU Bus 112 and PCI Bus 122. PCI Bus122 in turn is connected to an Ethernet device 126, an SCSI Host BusAdapter 124, and an ISA Bus Bridge 128. SCSI Host Bus Adapter 124 isconnected to SCSI Bus 130, which is connected to one or more hard disks132, and one or more CD-Rom drives 134. ISA Bus 135 is connected to oneor more UART devices 136, and to one or more floppy drives 138.

[0055] As known, the devices necessitate pieces of code named drivers tobe able to correctly operate. In accordance with one aspect of thisinvention, the tendency is to systematically have one driver for eachdevice, with the driver services being those required for the device.

[0056] Accordingly, the device driver framework has the structure shownin FIG. 2. The micro kernel basic services, including CPU Interruptmanagement and memory management, form a module 205, with PCI Bus Bridgedriver 218 connected thereto. Module 218 in turn receives connectionfrom SCSI Host Bus Adapter driver 224, and from ISA Bus Bridge driver228, as well as from an Ethernet peripheral driver 226. SCSI Host BusAdapter driver 224 has one or more hard disk drivers 232, one or moreCD-Rom drivers 234. ISA Bus Bridge driver has one or more UART drivers236 and one or more floppy drivers 238.

[0057] The Interface layering will now be described with reference toFIG. 3. The interfaces specified by ChorusOS for the device driversimplementation are split logically in two sets:

[0058] Drivers/Kernel Interface (DKI), which comprise a set of servicesprovided by the microkernel 205 for driver implementation. In otherwords, all DKI services are implemented in the microkernel, and used bydevice drivers. Typically drivers for buses and devices connected to theCPU local bus will use all DKI services.

[0059] Device Drivers Interface (DDI), which comprises a set of servicesprovided by drivers for the driver clients implementation. In fact, adriver client may itself be a driver. For instance a device driver istypically a bus driver client. Thus, all DDI services are implemented ina driver, and used by the upper layer drivers, or directly by driversclient applications.

[0060] The DKI interface defines all microkernel services provided fordrivers implementation. These services are split in two categories.Common DKI services 207 have the same API for all platforms andprocessors, and are usually used by all kind of drivers, whatever thelayer level is. Processor family specific DKI services 206 may have adifferent API for each different processor family and are usually usedonly by the lowest-level drivers, i.e. drivers for buses and deviceswhich are directly connected to the CPU local bus 112 (FIG. 1).

[0061] The Processor family specific DKI services 206 cover: Processorinterrupts management, Processor caches management, Processor specificI/O services and Physical to virtual memory mapping. Some or all ofthese services exist, and may be implemented in known fashion. These DKIservices operate with the CPU bus (the root of the device tree) to someextent like DDIs with devices; there is a DKI service for eachparticular CPU bus function, and the design of the DKI services isrendered modular, thus improving the portability.

[0062]FIG. 3 also shows that the other drivers have interfaces arrangedas DDI services as follows:

[0063] DDI 219 for PCI bus bridge driver 218;

[0064] DDI 225 for SCSI host bus adapter driver 224;

[0065] DDI 229 for ISA bus bridge driver 228; and

[0066] DDI 240 diagrammatically showing the DDIs for all other enddrivers, communicating with driver clients 250 in application programs.

[0067]FIG. 4 shows a driver registry 40, having a particular driverrecord 401, and a Device Registry 50, having a particular device record501.

[0068] Many drivers exist. Only one is shown in FIG. 4 for clarity. Adriver 6 has driver program code (“driver text”) 60 and global driverdata 61, comprising:

[0069] a driver operations section (“driver ops”) 612, adapted toprovide services or functions, using driver program code 60, and

[0070] a driver registry entry section (“DrvRegEntry”) 611. Driverrecord 401 has a pointer to “DrvRegEntry” 611 of the particular driver 6being considered. For initialization and shut-down, the “DrvRegEntry”611 may optionally define entry points to device independent routines inthe driver, e.g. “drv_probe”, “drv_bind”, “drv_init” and “drv_unload”,to be discussed hereinafter.

[0071] As shown in FIG. 5, the exemplary device structure of FIG. 1 canbe rearranged into a tree, having a root 500 constituted by the CPU Bus.The CPU and RAM appear as leaf nodes 510 and 511. PCI Host Bus Bridge isan internal node or “bus/nexus” 512, which has subnodes SCSI HBA 521,and ISA Bus Bridge 522, and leaf node 520 for an Ethernet device. Inturn, SCSI HBA 521 node has subnodes 531 for the hard disk and 532 for aCDROM drive. Also ISA Bus Bridge node 522 has subnodes 534 for the UARTand 536 for a floppy disk drive. The peripheral devices are leaf nodes(more briefly “leaves”) in the tree, here CPU, RAM, Ethernet, Hard disk,CD-Rom, UART and floppy.

[0072] As above indicated, e.g. one or more hard disks may be provided.In the case of two hard disks, there are of course two hard disk leafnodes connected e.g. to SCSI HBA nexus 521.

[0073] In this invention, driver 6 of FIG. 4 is a generic driver objector “global” driver section, which is not used as such by devices. Inaccordance with the concepts of object programming, the devices needingthe services of the particular driver 6 will use “instances” of theobject (object class) defined by driver 6.

[0074] Such an instance basically comprises “local” driver data 71,defining the instance, together with the global driver section. Thelocal driver data 71 comprises data forming an “internal” pointer to thedriver object 6. “Internal” means that the pointer connects the driverinstance to the global driver section within the driver. In other words,a driver instance comprises its local driver data plus the global driversection. Preferably, the local driver data 71 also comprises dataforming an “external” pointer to at least one other driver, typicallythe parent driver (the root's parent driver are the DKI services).

[0075] The local driver data 71 may also include local device-orienteddata, defining, in section 712:

[0076] data defining the current condition of the local device, and

[0077] a device handle, for the local device associated with the driverinstance.

[0078] Consideration is now given to the case of a driver instantiationfor a leaf device in FIG. 4, i.e. one of the devices directlycommunicating with driver clients in FIG. 3. Such a leaf driver instanceis also associated with a “Device registry entry”. In FIG. 4, the deviceregistry entry is shown as a section 711 in “local” device data 71 ofthe driver instance (However, the Device registry entry mayalternatively be associated with the corresponding record 501 in deviceregistry 50). In any case, each item in the Device Registry 50 in FIG. 4has a corresponding “DevRegEntry” structure 711, which is exemplified inpseudocode in Exhibit A-1, and commented in Exhibit B-1.

[0079] Device registry 50 forms the basis of a client-to-[leaf]-driverlinking mechanism. For subsequently reaching a bus/nexus driver, achild-to-parent-driver linking mechanism is used.

[0080] As shown in FIG. 6, the device related software may also bedefined and split in accordance with a tree structure, in parallelismwith the device tree. The tree includes a root node 550, which has a CPUmanagement leaf 560, for example for interrupts, and a memory managementleaf 561, plus the PCI HBB driver nexus 562. This nexus in turn has anEthernet driver leaf 570, and two sub-nexus:

[0081] SCSI HBA driver 571, with hard disk driver leaf 581 and CD-ROMdriver leaf 582, and

[0082] ISA BB driver 572, with UART driver leaf 584 and floppy driverleaf 586.

[0083] As reflected by the dashed line frame in FIG. 6, a portion of thedevice related software, e.g. the CPU management and memory management,is part of the nucleus of the OS, rather than of the driver framework assuch. When restricting the driver tree of FIG. 6 to the drivers per se,its root is the PCI HBB driver nexus 562.

[0084] The device tree of FIG. 5 is preferably represented as such inthe code. By contrast, the driver tree of FIG. 6 is virtual, i.e. isdefined only by the fact each device in the device tree of FIG. 5 shouldnormally have a corresponding driver instantiation.

[0085] A computer in operation will now be considered. It is assumedthat driver registry 40 contains drivers as required to satisfy thefollowing conditions:

[0086] each bus/nexus node in operation has found at least one drivermatching its own needs, and a driver instance for that nexus node hasbeen created;

[0087] each leaf node in operation has been provided with at least onedriver matching its own needs, and a driver instance for that leaf nodehas been created;

[0088] each device having a leaf driver instance has a Device registryentry, accessible through device registry 50.

[0089] When a driver client 250 wishes to access a particular leafdevice, e.g. hard disk 132, to perform a given operation on it, theprocess is as follows:

[0090] the device is searched for in device registry 50, finding e.g.record 501, and the DevRegEntry 711 in the driver instance 232corresponding to that device;

[0091] in turn, DevRegEntry 711 points to driver operations in 612,which are thus made available to the device;

[0092] the adequate device handle is given by the data in 712; thishandle is a pointer to associate internal data of the driver instancewith the device using these data;

[0093] a pointer to the corresponding device 715 is also available (or,if the device tree structure is used at this stage, a pointer to thecorresponding device node in the device tree);

[0094] if the operation needs, another driver is called to help inexecuting that operation, using further external pointer(s); this isrepeated as necessary.

[0095] Thus, in a computer in operation, all that is necessary toprocess a call from an application (client 250) to a particular leafdevice may be made available by the cooperation of device registry 50with the corresponding local data 71.

[0096] A more detailed description will now be given, including thedriver initialization (and, optionally, shutdown).

[0097] The common DKI services 207 include a “DKI thread”, launched bythe microkernel at initialization time. The DKI thread is part of thenucleus (or nucleus actor in ChorusOS) of the operating system. The DKIthread serves as a mechanism to synchronize same calls to DKI and DDIservices issued from different threads at drivers initialization time,and also at runtime (if required, e.g. for initialization and shutdownof drivers). Thus, using the DKI thread avoids the need for othersynchronization mechanism (locks) in the driver implementationsthemselves.

[0098] Normally, all calls related to initialization/shutdown of thedrivers are done implicitly in the context of the DKI thread. Since thecorresponding driver routines are called directly from the DKI thread,there is no need for code taking care of synchronization. However, adriver may explicitly use DKI thread services to ensure synchronizationin certain special cases, like hot-pluggable device drivers, or deferredinitialization and shutdown process, which are described later on.

[0099] The basic calls to the DKI thread are exemplified in pseudocodein section A-2 of Exhibit A, and described in more detail in section B-2of Exhibit B. The contexts in which a caller is allowed to invoke eachservice are shown in the table T1 of FIG. 14. The possible callingcontexts in the tables are:

[0100] Base level: the service may be called from any thread base levelcontext.

[0101] DKI thread: the service may be called from DKI thread context.

[0102] Interrupt: the service may be called from interrupt context, i.e.from the context of an interrupt handler.

[0103] Blocking: the service may block and preempt the caller.

[0104] Other features of the Common DKI 207 are: Device tree, Driverregistry, and Device registry. Common DKI 207 may also include otherservices not related to this invention: General purpose memoryallocation, Timeout, Precise busy wait, Special purpose physical memoryallocation, System event management, Global interrupts masking, andSpecific I/O services. Again, there is a DKI service for each particularcommon function, i.e. the design of the DKI services is renderedmodular.

[0105] The device tree is a data structure which provides a descriptionof the hardware topology and device properties. Tree services areavailable from a device tree API, exemplified in pseudocode in sectionA-3 of Exhibit A, and described in more detail in section B-3 of ExhibitB. In these examples, “DevNode” is an abstract type designating a devicenode object, and is opaque for the driver. More precisely:

[0106] functions A-3.1 described in B-3.1 define a low-level API sectionrelated to the device tree browsing;

[0107] functions A-3.2 described in B-3.2 define a low-level API sectionrelated to the device tree topology modification;

[0108] functions A-3.3 described in B-3.3 define a low-level API sectionrelated to the properties of the device tree nodes;

[0109] From the above low-level functions, an API section offeringDevice tree high-level services is built, implementing some usefulservices for building and searching the device tree, to avoid having lowlevel code implemented in all device tree users. Functions A-3.4described in B-3.4 define these Device tree high-level services. TableT2 of FIG. 15 specifies the contexts in which a caller may be allowed toinvoke each low-level or high level service. Building the abovefunctions on a tree structure is considered accessible to men skilled inthe art, using Exhibits A and B as necessary.

[0110] The hardware topology of the devices is specified in terms ofparent/child relationships. Each device node in the tree is associatedwith device properties, which are device specific. A device property isa “name/value” pair. The property “name” is e.g. a null terminated ASCIIstring. The property “value” is a sequence of bytes specified by the“length/address” pair. The property value format is property specificand may have to be standardized between the given producer and itsconsumers. For instance, certain device node properties are related tothe bus resources required and/or allocated for the device (e.g.interrupt lines, I/O registers, DMA channels). Such properties arepreferably standardized, in order to be understood by the bus driver aswell as by device drivers connected to the given bus.

[0111] Preferably, a device registry microkernel module (“deviceregistry API”) implements a data base of driver instances servicingdevices currently supported by the operating system. The device registrydata base has been populated by drivers at device initialization time.The device registry data base is accessed by driver clients in order toobtain a pointer to the driver instance servicing a given (logical)device.

[0112] Device registry management services or functions (the API) areexemplified in pseudocode from A-4.1 to A-4.8 and described incorresponding sections B-4.1 to B-4.8. Table T4 in FIG. 17 specifies thecontexts (as defined above) in which a caller is allowed to invoke eachservice. Note that only the “svDeviceLookup”, “svDeviceRelease” and“svDeviceEntry” microkernel calls should be used by driver clients 250.The rest of the API is dedicated to device drivers.

[0113] Preferably, the driver code in each driver 6 contains a “main”routine, for performing self-registration of the driver in Driverregistry 40.

[0114] Driver registry module 40 implements a data base of drivers,which is useful for driver initialization and shutdown. Each item in theDriver Registry 40 in FIG. 4 has a pointer to the “DrvRegEntry”structure 611, which is exemplified in pseudocode in A-5, and commentedin B-5.

[0115] Driver registry management services or functions (an API) areexemplified in pseudocode from A-6.0 to A-6.6 and described incorresponding sections B-6.0 to B-6.6. Table T3 in FIG. 16 specifies thecontexts (as defined above) in which a caller is allowed to invoke eachservice.

[0116] Each driver's “DrvRegEntry” structure 611 may include one or moredriver management oriented functions, or driver entry points. The threefollowing functions may be invoked by a bus/nexus driver when the“bus_class” specified in the driver registry entry matches the bus/nexusclass:

[0117] “drv_probe”, which is able to detect device(s) residing on thebus, with a view to create a device node for each such device.

[0118] “drv_bind”, which checks whether a detected device may beserviced by the driver.

[0119] “drv_init”, which creates an instance of driver servicing the“bound” device, and performs other steps as necessary for fulldriver/device cooperation.

[0120] A fourth function, “drv_unload”, may be invoked by the driverregistry module when an application wishes to unload a driver componentfrom the system.

[0121] In “DrvRegEntry” structure 611, the “bus_class” and “bus_version”fields specify a parent bus/nexus API required for the driver. Such anAPI is provided to the driver as a structure of indirect functionsimplementing the bus API service routines. For instance, the “pci” busAPI is specified by the “PciBusOps” structure, the “is a” bus API isspecified by the “IsaBusOps”. When a bus driver invokes the “drv_probe”or “drv_init” driver's routine, it gives a pointer to the structure ofthe bus service routines, in its driver global section. The structuretype corresponds to the “bus_class” field value.

[0122] Accordingly, the following will refer to a “bus_ops”+“bus_id”pair, which specifies the parent driver of a current driver. “bus_ops”points to a structure of service routines implementing a bus driver APIin the parent driver. Such a structure is bus class specific, i.e.several such structures may exist within the “driver_ops” of the parentdriver, implementing several bus classes. The structure being aimed atby “bus_ops” corresponds to the “bus_class” specified by the driverregistry entry of the current driver. “bus_id” is an opaque for thecurrent driver. It must be passed back to the parent bus driver, e.g.when the “open” bus service routine is invoked.

[0123] This invention uses mechanisms implemented in order to supportthe dynamic loading/unloading of a driver component, the dynamicdiscovering/enumeration of devices residing on a bus, the dynamicinitialization/shut-down of a driver instance. These issues concernbus/nexus as well as device drivers.

[0124] The way the computer starts operation will now be considered.

[0125] It should be reminded that the device tree structure is accessedin the DKI thread context only, to ensure access synchronization. Inmany cases, driver routines which typically examine/modify the devicetree are already invoked by the DKI thread. For instance, the driverprobing, initialization and shut-down code is executed by the DKIthread. In a case when a driver needs to access the device tree at runtime, a driver routine which uses the device tree API must be explicitlycalled in the DKI thread context. The same rule is applied to the driverclients: a driver client must always switch to the DKI thread contextwhen needing to access the device tree structure.

[0126] The device tree data structure may be built either statically ordynamically:

[0127] in the static case, the device tree is populated by the OSbooter. For instance, the OS booter may include a pre-defined sequenceof device tree function calls. Another possibility for the OS booter isto build the device tree from a hardware description provided byfirmware.

[0128] in the dynamic case, the device tree is populated at systeminitialization time using an enumeration/probing mechanism. The devicetree is populated by propagating from parent to children.

[0129] It is possible to combine both methods: for example, an initial(non complete) device tree may be provided by the OS booter, and willlater be completed dynamically using an enumeration/probing mechanism.The device tree structure may also be modified (extended/truncated)dynamically at runtime, because of the hot-plug insertion and/or removal(e.g. PCMCIA cards).

[0130] The following is a typical computer starting sequence (as far asdevices and drivers are concerned).

[0131] The first phase is the driver registration time (800, FIG. 7),initiated by the OS nucleus. At step 802, a driver component isdownloaded in some way: it may be built-in to the OS bootable image, orit may be downloaded dynamically as a supervisor actor using e.g. the“afexec” system call of ChorusOS. At step 804, the system calls the“main” routine which performs the self-registration: it invokes the“svDriverRegister” microkernel call, passing as an argument a“DrvRegEntry” data structure which specifies the driver componentproperties. The driver is now added in driver registry 40 at step 806.Its DrvRegEntry structure is now accessible to the OS nucleus, e.g.through a pointer. Steps 804 and 808 continue until all downloadeddrivers appear in driver registry 40 (step 810).

[0132] After the driver components have self-registered, the futuredriver management is mostly driven by the parent bus/nexus driver ofeach driver component, using the properties specified in the“DrvRegEntry” structure of that driver.

[0133] The second phase may be called “enumeration/probing”. At thattime, the OS nucleus starts execution of an iterative and/or recursiveprocess, using the device tree, the device registry, the driver registryand certain of the driver operations. In the exemplary embodiment, thisprocess forms a cascade of internested processes of “bus/nexus driverinitialization”.

[0134] Generally, an elementary phase of the process is as follows:

[0135] s0. a bus-nexus driver, bound to its device, is considered,

[0136] s1. the bus-nexus driver is initialized as a driver (like a leafdriver is initialized),

[0137] s2. in the case of a bus-nexus driver, the driver initializationadditionally comprises (normally):

[0138] s21. a “probing” step for finding child devices of the currentbus-nexus driver,

[0139] s22. a “binding” step for matching such child devices withcorresponding drivers, and

[0140] s23. an “init” step for initializing the driver/device pairs, bycreating driver instances as necessary.

[0141] The iteration is due to the fact that, whenever step s23initializes a bus nexus driver, a nested similar process is initiated,starting again at step s0, as it will be seen.

[0142] It should be reminded that, in FIG. 6, the root node 550 is theDKI services, which is part of the nucleus. Initiation of the secondphase begins with a “bus/nexus driver initialization”, applied to the(driver) root, whose parent is the DKI thread. In the example, thedriver root is the PCI Bus Bridge driver 218. The corresponding node inthe device tree is the PCI bus node. The required condition andresources for the PCI bus to operate are supposed to be prepared by thenucleus.

[0143] The “bus/nexus driver initialization” will now be described ingeneral, i.e. whatever the bus nexus is. FIG. 8 shows the main steps ofsuch a Bus Driver Initialization Routine 900 (or “BDIR”).

[0144] The first step 902 of the initialization of a given bus/nexusdriver is similar to the leaf device driver initialization process ofFIG. 12, and will be described in connection therewith. At this point,it is assumed that, after step 902, the given bus/nexus driver is ableto access its hardware (e.g. internal bus bridge registers), that it hasestablished connection to its parent bus/nexus driver, that it can useservices implemented by its parent driver. (Initially, for the rootdriver, here the PCI bus, this has been done by the nucleus).

[0145] Then comes step 910 of “probing”, which may result into thecreation of child device nodes in the device tree. This will bedescribed in more detail with reference to FIG. 9.

[0146] Step 919 deals with allocating resources to the newly entereddevices at step 910, as defined in step 918 of FIG. 9 (to be described).Each device node specifies bus resource properties required for theassociated device: some of the required bus resources may be hardwired(e.g. fixed IRQ); other required bus resources may be configurable, andsubject to some constraints (e.g. device address decoder constraints).At step 919, the bus/nexus driver iterates through existing child nodesin order to allocate configurable resources (taking the constraints intoaccount) and to check possible resource conflicts. If a resourceconflict is detected, the bus/nexus driver behaviour is implementationspecific. The bus/nexus driver should never activate any driver on anode for which bus resources are not allocated successfully.

[0147] Then, step 920 performs a driver-to-device binding, which will bedescribed with reference to FIG. 10. Finally, at step 930, driverinstances are created in the child device nodes. This will be describedwith reference to FIG. 11.

[0148]FIG. 9 illustrates the probing step 910 in more detail. A“current” bus/nexus driver (911) searches in the driver registry database for all drivers satisfying the following condition: the parentdevice class specified in the driver being searched must match the classof “current” bus/nexus, or one of its classes (913). The drivers beingfound (914) will form the first level of children of the “current”bus/nexus driver (the one considered in 911). For each such driver(implementing the “drv_probe” entry point), step 918 immediatelyexecutes another “drv_probe”.

[0149] The pseudocode given in Exhibit A.7 and commented in Exhibit B.7illustrates a typical probing loop in a bus/nexus driver, creatingdevice nodes as required. “drv_probe” is called with three arguments:“dev_node”, specifying the parent device node and a “bus_ops” and“bus_id” pair specifying the parent device driver. The “drv_probe”routine is optional. If it is absent, the “drv_probe” field in“DrvRegEntry” is set to NULL.

[0150] In general, the operation of a probe routine may be summarized asfollows:

[0151] The probe routine should avoid creating redundant nodes.

[0152] The probe routine specifies the following device node properties,

[0153] a physical device ID, enabling the bus driver to find theappropriate device driver for this device node. Preferably, the deviceID is bus class specific. For instance, on PCI bus, the device ID is thevendor/device IDs pair.

[0154] resource requirements, so that the bus driver can reserveresources required to initialize the device.

[0155] The probe routines will now be considered in more detail. Infact, there are two kinds of probe routines:

[0156] generic (i.e. bus class specific only), like a self-identifyingbus (e.g. PCI) enumerator;

[0157] device specific (i.e. bus class and device specific), like adevice probing code on an ISA bus.

[0158] Accordingly, child driver offering multiple probe routines for agiven parent bus may be found in the driver registry. They may beprocessed in any desired order.

[0159] In addition, the probe routines may be invoked at run time when,for example, a device insertion is detected on the bus. In the lattercase, the probe routines must be extremely careful about active devicenodes, i.e. existing device nodes for which the device drivers have beenalready started and may be already in use.

[0160] The following rules are preferably respected by generic anddevice specific probe routines:

[0161] The generic and specific probe routines may access the devicehardware only through the bus service routines. The bus resources neededto access the device hardware (e.g. I/O registers) may be allocatedthrough the bus service routines (“resource alloc”). This prevents theprobe routine to access hardware which is currently in use. Uponunsuccessful probing, the used hardware resources is released throughthe bus service routines (“resource free”).

[0162] No probe routine (whether generic or device specific) may deletean active device node, or modify its properties (An active device nodeis a node for which a device driver is already running; such nodes areflagged with the “active” property).

[0163] Device specific probe routines have higher priority than genericones, i.e. device specific probe routines are allowed to overrideproperties in an existing node or to delete an existing node, wheninactive, while generic probe routines are not.

[0164] No probe routine may create redundant nodes. When a probe routineis to create a device node, then it verifies that no other node existfor this device. Probing is normally avoided if the probing routine maycreate redundant nodes.

[0165] Implementing such probing mechanisms within a driver isconsidered accessible to men skilled in the art.

[0166] A preferred implementation of the device-to-driver binding step920 is shown in more detail on FIG. 10.

[0167] A “current” bus/nexus driver (921) searches in the driverregistry data base for all drivers satisfying the following condition(923): the parent device class specified in the driver being searchedmust match the class of “current” bus/nexus, or one of its classes (andimplement the “drv_bind” entry point). Each of the drivers being found(924) may now be bound to known device child nodes, found by theprobing, and appearing in the device tree. Steps 926 and 927 scanthrough these child device nodes, and, in each, the “drv_bind” routineis invoked at step 928. When all children for all matching drivers havebeen seen, step 924 goes to the end.

[0168] The pseudocode given in Exhibit A.8 and commented in Exhibit B.8illustrates a typical binding loop in a bus/nexus driver.

[0169] The driver-to-device binding mechanism may have variousimplementations:

[0170] a very simple bind routine may be implemented by the child devicedriver itself. Such an implementation is device specific, and appliesonly to devices known by the driver as compatible with a referencedevice for which the driver is written.

[0171] on the other hand, the system may need to support after-markethot-plug devices, and consult some network look-up service to locate thedriver for a new device. In such a case, it may be preferable to use ageneric separate binder driver, dedicated to implementing a smartdriver-to-device mapping and a driver component downloading (without theprobe and init routines). Of course, such a (generic) binder will betreated like the other driver components.

[0172] A preferred implementation of step 930 is shown in more detail onFIG. 11.

[0173] At step 932, each bus/nexus driver explores its child devicenodes in the device tree. It tests whether any of these devices is boundto a driver, but not active (933). This means that the driver has notyet been initialized, and should be started and instantiated for thatdevice. Then, in the described embodiment, a complete checking is againperformed: for any device verifying the condition, the driver registryis again explored (935); if a driver (or a further one) is found at step936, then step 937 checks whether a) the required bus class of thatfound driver matches one class of the bus/nexus, and b) the driver namematches the one bound to the device node being considered. If so, step940 calls the “drv_init” routine of that driver. The “drv_init” iscalled with three arguments. The “dev_node” argument specifies thedevice node for which a device driver instance should be created. If thedrv_init succeeds in activating the device, test 939 returns to 933.Otherwise, or if step 937 indicated misfit, control is returned to step936. If no adequate driver is found, test 936 returns control to step933, for processing another child device, if any.

[0174] The above described complete checking is of interest because thesame routine may be used for “hot” device and driver management as well.When used at initialization only, the routine may be simplified.

[0175] Preferably, when a driver instance is activated by a bus/nexusdriver, the child driver establishes a connection to its parentbus/nexus driver, while specifying a call-back event handler. The parentbus/nexus driver may use the call-back event handler mechanism e.g. toshut down the child driver instance later, if required.

[0176] Step 940 will now be described in further detail.

[0177] If the child is a leaf child node, the process to be describedwith reference to FIG. 12 is executed, and control is given to step 939of FIG. 11.

[0178] If, by contrast, the child is a bus-nexus, the process of FIG. 8is resumed with the child. This means that a new BDIR (bus driverinitialization routine) is recursively called, to be nested within thecurrent one. The status of the current BDIR is stored before initiatingthe new one. This new BDIR may in turn result into a further BDIR, andso on, until reaching a “leaf-only” BDIR, where the child level includesleaf nodes only. When such a leaf-only BDIR terminates, by the “N”output of step 933, control is returned to the immediately precedingBDIR, until it terminates in turn. This is repeated until the initialBDIR terminates, indicating the whole device tree has been scanned.

[0179] The pseudocode given in Exhibit A.9 and described in Exhibit B.9illustrates a typical initialization loop in a bus/nexus driver.

[0180] The purpose of “drv_init” is to create an instance of driverservicing the given device, to perform a device hardware initializationand to register the driver instance in the device registry (in theexample, for leaf only). Typically, “drv_init” would read the device andbus node properties in order to obtain the assigned bus resources andtunable parameters related to the bus/device.

[0181] The “drv_init” routine is optional. In its absence, the“drv_init” field is set to NULL. A typical example of a probe-onlydriver is a self-identifying bus enumerator (e.g. PCI enumerator) whichis implemented as a driver. Such a driver has the “drv_probe” routinewhich enumerates devices residing on the bus and creates device nodes,but needs no “drv_init” routine.

[0182] The initialization process of a device will now be considered inmore detail. FIG. 12 shows the main steps of the initialization process“drv_init” of a leaf device driver (990).

[0183] At step 992, the driver establishes connection to the parent busdriver calling its “open” function. In calling “open”, the child driverspecifies call-back handlers, which will be used by the parent driver tomanage the device instance driver (e.g. to shut down the driverinstance). Similarly, global bus events (e.g. a catastrophic bus error)are delivered to the driver through a call-back handler.

[0184] Once the child-to-parent connection is established, the drivermay use services provided by the parent driver. At step 994, the childdriver asks its parent driver to make available the bus hardwareresources needed for its bound device. In fact, the bus resources neededfor the device have been specified as properties in the device node, andsuch resources have been already allocated by the parent bus/nexusdriver prior to the “drv_init” invocation. Thus, “making available” agiven bus resource (e.g. device I/O registers), means that the driverobtains an appropriate property value and calls an appropriate bus/nexusservice routine.

[0185] Then, at step 996, the child driver initializes the devicehardware to an operational state. Finally, at step 998, the (leaf)driver performs the self-registration in the device registry. Thisdeclares that a new device, together with its device driver instance, isavailable in the system.

[0186] Once the device (i.e. the device driver instance) is registered,a driver client may find such a device in the registry (using the deviceregistry API) and may perform operations on the device, calling driverservice routines exported through the device registry entry. The driveris not obligated to register any device driver instances and offer anydevice service routines through the device registry. The device driverinstance registration is only required for clients who plan on findingtheir devices through the device registry. If other client-to-driverbinding mechanisms are in use, the associated devices need not take partin the device registry.

[0187] The (leaf) “drv_init” routine is called in the context of DKIthread. It makes possible to invoke directly the bus/nexus and DKIservices allowed in the DKI thread context only.

[0188] Step 902 of FIG. 8 may now be described in detail. Like a leafdriver, initialization of a bus/nexus driver comprises enabling it toaccess its hardware (e.g. internal bus bridge registers), to establishconnection with its parent bus/nexus driver and to use servicesimplemented by its parent driver.

[0189] So, step 902 might include all steps 990-998 of FIG. 11. However,in the preferred embodiment, when initializing a bus/nexus driver, step998 is omitted, i.e. the nexus driver does not implement registering itsbus/nexus instance and the corresponding device in device registry 50.Thus, upon a call in operation from a driver client 250:

[0190] the client to (leaf) driver binding, aiming at a leaf node, usesthe device registry;

[0191] then a binding mechanism (child to parent) is necessary to enabletravelling within the tree from the leaf towards the root; rather than achild-to-parent driver binding mechanism, a parent to child action isused instead: each parent bus/nexus driver provides its child with apointer to its service routines vector and its identifier, for use inoperation (and also e.g. when the “drv_probe” or “drv_init” routine ofthe child driver will be invoked). This does not use the deviceregistry.

[0192] In summary, when starting the computer, a full device and driverscanning may be performed as follows. A first “Bus Driver Initializationroutine” or BDIR is launched, with the “current bus/nexus node” beingthe (driver) root, i.e. the pci bus in the example. Loops perform a)probing, b) binding, c) creation of driver instances (as appropriate ineach case). This builds the child level of the current bus/nexus node.Whenever the child level comprises another bus/nexus node, phase c)launches a nested recursive call of the BDIR, with that bus/nexus nodeas a “current bus/nexus node”.

[0193] Thus, considering a given nexus (sub)node:

[0194] the child node level in the device tree is constructed by asingle probing step;

[0195] for the subsequent driver initialization, the subtree of thegiven (sub)node is explored following a branch, until a leaf-only levelis found, then going back to the last nexus to follow another branch,and so on until the whole subtree has been seen.

[0196] Although the above described ways of scanning the device tree fori) probing, ii) binding, and iii) initializing drivers recursively arepreferred, other scanning methods may be contemplated by men skilled inthe art, using the same principles.

[0197] Modification of the device and driver framework in operation willnow be considered. The change may be due to two different events:

[0198] the system sees a new driver (load handler),

[0199] a device is added/removed (hot plug).

[0200] A given nexus device driver has a handler named “Driver LoadHandler”, which is invoked by the parent bus/nexus driver, when a newdriver appears in the system in operation: for example, a new driver isdownloaded at run time, and has just registered in the driver registry40, using its “main” routine. The load handler address is given to the“given” bus/nexus driver when a connection is established between thenew child driver and the parent bus/nexus driver.

[0201] The load handler is optional. Normally, a leaf device driver isnot interested about such an event. The load handler is usually used bya bus/nexus driver (e.g. bus-to-bus bridge), which is interested inapplying a newly downloaded driver to its child devices which are notserviced yet.

[0202]FIG. 13 shows the actions 1010-1030 taken by the load handler.They are similar to steps 910-930 shown in FIG. 8 for the bus/nexusdriver initialization. The process normally starts again from the rootnode, i.e. the pci bus in the example. Step 902 is omitted, since thebus/nexus device is already initialized.

[0203] At step 1010, the bus/nexus driver invokes the probe routinesregistered in the driver registry matching the bus/nexus class. Theprobing loop of Exhibit A.7 is used again. The probe routines alreadyinvoked at initialization time will likely be invoked again. Asmentioned, a probe routine must be aware about existing device nodes inorder to avoid creation of redundant device nodes. In addition, a proberoutine must explicitly ask for bus resources in order to avoidconflicts with bus resources currently in use. In this way, the activedevice nodes and associated running driver instances are protectedagainst a perturbation caused by the run-time probing.

[0204] Thus, the probe routine implemented by the newly downloadeddriver will likely discover one or more device(s) previously unknown inthe system, with one or more corresponding new child device nodes beingcreated. If so, at step 1019, the bus/nexus driver will check/allocatebus resources required for such new device nodes.

[0205] Step 1019 is more sophisticated than corresponding step 919 ofFIG. 8. In order to satisfy such a run-time resources request, thebus/nexus driver may need to confiscate resources already assigned toexisting (“older”) device nodes; however, in so doing, the bus/nexusdriver is not allowed to confiscate resources in use, i.e. resourcesassigned to active “older” device nodes. The driver instance associatedwith such an active “older” node must be shut down by the bus/nexusdriver prior to any resource confiscation. In order to shut down an“older” driver instance, the bus/nexus driver sends a shut down event tothe “older” child driver, requesting to close the“older”-child-to-parent driver connection, i.e. to invoke “close”. Oncethe connection is closed, the “older” device node becomes inactive andthe bus/nexus driver is able to confiscate bus resources assigned tothat “older” node. In such a case, the bus/nexus driver should start the“older” driver instance again, invoking the driver “drv_init” routine,to have the driver operate when its resource requirements may besatisfied.

[0206] Once the bus resources allocation is done, the bus/nexus driveriterates through the child nodes and, for each inactive device node, ittries to determine a driver component which should be applied to thegiven device, and does the binding at step 1020, which is the same asstep 920. Once such a driver component is found, the bus/nexus drivercalls the driver “drv_init” routine, at step 1030, which is the same asstep 930.

[0207] Finally, the bus/nexus driver invokes the child load handlers (ifany) in order to propagate the loading process downstream (i.e. fromparent to child). In such a way, the loading process is recursivelycontinued by the child driver load handler(s).

[0208] The load handler is called in the context of DKI thread. It makesit possible to invoke directly the bus/nexus and DKI services allowed inthe DKI thread context only.

[0209] The case of hot-pluggable device drivers will now be considered.In case of hot-plug, the initialization/shutdown process has to beexecuted at runtime, rather than as part of the kernel/driversinitialization process. In such a case, drivers should use DKI threadservices to explicitly synchronize with already running drivers.

[0210] The hot-plug insertion event is typically reported via interrupt.In order to be notified when the hot-plug insertion occurs, the busdriver connects an interrupt handler to an appropriate interrupt source.

[0211] Thus, the bus driver typically detects the insertion event atinterrupt level. In order to process such an event, the bus driverinvokes “svDkiThreadTrigger” requesting the DKI thread to execute a busdriver routine which implements the hot-plug insertion procedure. TheDKI thread serializes all actions related to the initialization andtermination. In addition, it allows the insertion procedure to invokedirectly the parent bus/nexus and DKI services allowed in the DKI threadcontext only.

[0212] The hot-plug insertion processing again goes through main stepssimilar to steps 1010-1030 of FIG. 13, i.e.:

[0213] discover a new device inserted to the bus and create the devicenode associated with this device,

[0214] allocate bus resources for the new node,

[0215] bind a driver to the new node,

[0216] create a driver instance associated with the new node.

[0217] Actions taken by the hot-plug insertion are very close to theactions taken by the load handler, because once a new child nodeappears, the bus driver behaviour is always the same. It tries toallocate bus resources required for this node and it tries to apply adriver to this node. It does not matter why a new device node hasappeared (In case of load handler, a new device may appear because of anew probe routine having been running).

[0218] The driver event handler is invoked by the parent bus/nexusdriver when a bus/nexus event occurs. The event handler address is givento the bus/nexus driver when a connection is established between thechild driver and its parent bus/nexus driver. The event handler may becalled as an interrupt handler and therefore the event handlerimplementation must be restricted to the API allowed at interrupt level.

[0219] Among all events which are mostly bus/nexus class specific, thereare three shut down related events (specified by the common bus API)which are discussed in this section:

[0220] [xxx_]SYS_SHUTDOWN—system (emergency) shut down. The prefix “xxx”may mean “DKI”, “BUS”, etc., to the extent the event semantics are thesame for all such events. The SYS_SHUTDOWN event notifies the driverinstance that the system is going to be shut down. The parent bus/nexusdriver requires the child driver instance to perform an emergency shutdown of the device hardware.

[0221] DEV_SHUTDOWN—normal device shut down. The DEV_SHUTDOWN eventnotifies the driver instance that a normal device shut down is requestedby the bus/nexus driver.

[0222] DEV_REMOVAL—surprise device removal. The DEV_REMOVAL eventnotifies the driver instance that the associated device has been removedfrom the bus/nexus and therefore the driver instance has to be shutdown.

[0223] In the general case, the shut down event processing goes throughthree phases: shut down prologue, shut down mode, shut down epilogue.

[0224] The first phase (called shut down prolog) is processedsynchronously within the event handler. The main purpose of the shutdown prolog is to notify driver clients (or child drivers) that the shutdown event has occurred, in other words, to propagate the shut downprolog downstream (i.e. from parent to child). After the shut down eventhas been processed by driver clients (or child drivers), the driverenters in the third shut down phase (called shut down epilogue).Basically, the shut down epilogue is invoked when the last reference onthe driver instance goes away. Between the shut down prolog andepilogue, the driver operates in a special mode (called shut down mode).In such a mode, the driver accepts only a subset of operations fromclients allowing to properly close connections to the driver.

[0225] Table T5 in FIG. 18 shows typical actions taken by the shut downprolog depending on the event type. Note that the notification mechanismused by the shut down prolog depends on driver type and it is differentfor the bus/nexus and leaf (device) drivers. The shut down prolog of thebus/nexus driver notifies the child drivers calling the child driverevent handlers. The shut down prolog of the leaf (device) drivernotifies driver clients calling the “svDeviceEvent” routine.

[0226] The SYS_SHUTDOWN prolog of a bus/nexus driver invokes the eventhandlers of child drivers connected to it. Once the invocation is done,the bus/nexus driver puts the hardware into a clean state. TheSYS_SHUTDOWN prolog of a leaf (device) driver does not notify driverclients about the system shut down event. The driver just puts thehardware into a clean state. In fact, the SYS_SHUTDOWN event isprocessed synchronously, i.e. within the event handler (In other words,the system shut down epilogue is empty). The only purpose of the“SYS_SHUTDOWN” event is to put the board hardware into a clean state inorder to properly perform the system reboot (or restart).

[0227] The “DEV_SHUTDOWN” prolog only notifies driver clients (or childdrivers) that the “DEV_SHUTDOWN” event has occurred. The real deviceshut down is deferred up to the “DEV_SHUTDOWN” epilogue. The“DEV_REMOVAL” prolog does the same as the “DEV_SHUTDOWN” one, and, inaddition, aborts all I/O operations in progress because, otherwise, suchoperations will never be completed. Aborted operations will return tocallers with an error code.

[0228] As soon as the shut down prolog is processed, the driver changesits internal state: it enters a shut down mode, in which it accepts onlya subset of operations from clients. Basically, the driver acceptsrequests to abort queued operations, to release previously allocatedresources, and to close connection to the driver. All other operations(like open a new connection, start an I/O operation) are refused by thedriver. In other words, in the shut down mode, the driver is waitinguntil a shut down epilogue condition is met, allowing clients toproperly close existing connections to the driver.

[0229] The “shut down” epilogue condition is met within a bus/nexusdriver, when the last connection is closed to the driver instance. Theshut down epilogue condition is met within a leaf (device) driver, whenthe device entry is released by the last driver client, i.e. when thecall-back release handler is invoked by the device registry. Note that,typically, the shut down epilogue condition is met when the driver isrunning in the DKI thread context. Indeed, the “close” service routineand call-back release handler are both called in the DKI thread context.Thus, in natural way, the shut down epilogue is processed in the DKIthread context. It makes possible to invoke directly the bus/nexus andDKI services allowed in the DKI thread context only.

[0230] Table T6 in FIG. 19 shows typical actions taken by the shut downepilogue depending on the event type. The “DEV_SHUTDOWN” epilogue putshardware into a clean state, releases system resources used by thedriver instance and, finally, closes connection to the parent driver(“close”). The “DEV_REMOVAL” epilogue is close to the “DEV_SHUTDOWN” oneexcept the device hardware is not touched by the driver, because(obviously) the device hardware is no more present on the parent bus.

[0231] When a shut down epilogue closes the last connection to theparent driver, the shut down epilogue condition would be met in theparent driver too. Then, the shut down epilogue is propagated upstream(i.e. from child to parent). If one of driver clients (or one of childdrivers) does not implement properly the shut down procedure (e.g.simply does not support the shut down), the driver may stay in the shutdown mode, while never meeting the shut down epilogue condition.

[0232] The Hot-plug Removal will now be described.

[0233] The hot-plug removal event is typically reported via interrupt.In order to be notified when the hot-plug removal occurs, the bus driverconnects an interrupt handler to an appropriate interrupt source.Hot-plug removal may include:

[0234] “surprise removal”, i.e. a device can be removed at any time withno warning. For instance, PCMCIA is a surprise removal device.

[0235] “non-surprise removal”, i.e. the device cannot be removed untilthe system is prepared for it. For instance, Hot-Plug CompactPCI is anon-surprise removal device.

[0236] The surprise removal interrupt notifies the bus driver that adevice has been removed from the bus. The bus driver interrupt handlerusually detects the removed device (and associated device node) usingbus specific status register(s). Once the device is detected, theinterrupt handler checks whether the device node is active.

[0237] If the device node is inactive (i.e. there is no driver instanceservicing this device), the only task of the bus driver is to update thedevice tree removing the device node. All bus resources associated withthe node becomes free. The bus driver is not able to accomplish thistask immediately at interrupt level because the necessary services canbe called in the DKI thread context only, and are not available atinterrupt level. In order to satisfy the invocation contextrequirements, the bus driver calls “svDkiThreadTrigger” requesting theDKI thread to invoke the removal procedure. Another reason to use theDKI thread is to serialize all actions related to the initialization andtermination.

[0238] If the device node is active, the bus driver must shut down thecorresponding device driver instance prior to invoke the removalprocedure. In order to accomplish this task, the bus driver invokes thedevice driver event handler, signalling the “DEV_REMOVAL” event. Infact, the bus driver performs the shut down prolog for the given driverinstance. In other words, the bus driver initiates the shut down processfor the device sub-tree starting from the removed device node.

[0239] As the last action of the shut down event processing, the devicedriver will close the connection to the bus driver and, at this moment,the bus driver will perform the removal procedure. The device noderemoval procedure is executed in the DKI thread context because the“close” service routine is called in the DKI thread context.

[0240] The “non-surprise removal” interrupt requests the bus driver toenable the device removal from the bus. The processing is the same asfor “Surprise Removal”, except the bus driver requests the normal deviceshut down (DEV_SHUTDOWN) rather than the device removal one(DEV_REMOVAL). In addition, once the device tree is updated, the busdriver enables the device removal. (The device removal enabling isusually signalled by a LED or/and by a card ejection mechanismun-locking).

[0241] Unloading a driver will now be discussed. The only means tounload a driver is a “Driver Unload Routine” or “drv_unload”. The“drv_unload” is a global per driver component routine. Therefore, inorder to implement unloading, the driver should handle a list of itsdriver instances.

[0242] The “drv_unload” routine is optional. In case when “drv_unload”is not provided by a driver, its “drv_unload” field is set to NULL, andthe driver code cannot be unloaded.

[0243] “drv_unload” is called by the “svDriverUnregister” routine of thedriver registry module, when an application wishes to unload the drivercomponent from the system. The purpose of “drv_unload” is to check thatthe driver component is not currently in use: e.g. the driver must checkfor each driver instance whether it is locked in the device registry.

[0244] On success, all device instances are removed from the deviceregistry and “drv_unload” returns “K_OK”. Otherwise “K_EBUSY” isreturned, the driver component will not be unloaded, its state is notchanged, all registered driver instances remain in place, and the deviceentries are unchanged in the device registry.

[0245] Since the “drv_unload” routine is called in the context of DKIthread, it can invoke directly the bus/nexus and DKI services allowed inthe DKI thread context only.

[0246] When “drv_unload” is called, the driver should go through thelist of driver instances, and check whether any of them is currently inuse. If a given instance is not used, the driver instance becomeinvisible for potential clients. Thus, if “drv_unload” returns “K_OK”,all previously created driver instances (if any) are deleted and allpreviously allocated system resources (if any) are released.

[0247] The driver unloading implementation is different for a bus/nexusdriver, using the standard child-to-parent driver binding mechanism, anda leaf device driver, using the client-to-driver binding mechanism basedon the device registry. (If another client-to-driver binding mechanismis used, the driver unloading implementation is binding mechanismdependent).

[0248] The “drv_unload” routine in a Bus/nexus Driver typically takesthe following actions:

[0249] step 1: check that the driver component is not in use.“drv_unload” iterates through the driver instances list and, for eachdriver instance, checks whether a connection is opened to the driverinstance. Once a driver instance with an open connection is found, theiteration is aborted and “K_EBUSY” is returned. Otherwise, “drv_unload”proceeds to step 2.

[0250] step 2: release resources associated with the driver component.“drv_unload” iterates through the driver instances list and, for eachdriver instance, releases all system resources associated with theinstance and, finally, closes the connection to the parent bus. Once theiteration is finished, “drv_unload” returns “K_OK”.

[0251] The fact that “drv_unload” is running in the DKI thread contextguarantees stability of the driver instances and open connections duringthe “drv_unload” execution: a new driver instance may be created only bythe “drv_init” routine and a new parent-to-child connection may be openonly by the “drv_init” or “drv_probe” routines. Both “drv_init” and“drv_probe” are invoked in the DKI thread context. Thus, “drv_init” and“drv_probe” are serialized with “drv_unload” by the DKI thread. On theother hand, if a bus/nexus driver supports hot-pluggable devices, it isup to the bus/nexus driver to implement a synchronization mechanism witha hot-plug insertion interrupt which may occur during the driverunloading.

[0252] The “drv_unload” routine in a (leaf) device driver typicallytakes the following actions:

[0253] step 1: check that the driver component is not in use.“drv_unload” iterates through the driver instances list and, for eachdriver instance, invokes “svDeviceUnregister” in order to remove thedriver instance entry from the device registry. If “svDeviceUnregister”fails (i.e. returns “K_EBUSY”), the iteration is aborted and“drv_unload” proceeds to step 2. Otherwise (i.e. all device instancesare successfully unregistered), “drv_unload” proceeds to step 3.

[0254] step 2 (fail): “drv_unload” iterates through the driver instanceslist and, for each driver instance which has been unregistered at step1, invokes “svDeviceRegister” in order to register the driver instanceagain. Once the iteration is finished, and the initial state of thedriver component has been restored, “drv_unload” returns “K_EBUSY”.

[0255] step 3: “drv_unload” iterates through the driver instances listand, for each driver instance, releases system resources associated withthe instance and, finally, closes the connection to the parent bus whenall resources associated with the driver component have been released.Once the iteration is finished, “drv_unload” returns “K_OK”.

[0256] It should be reminded that “drv_unload” is running in the DKIthread context. This guarantees stability of the driver instances duringthe “drv_unload” execution. Indeed, a new driver instance may be createdonly by the “drv_init” routine which is invoked in the DKI threadcontext too. Thus, “drv_init” is serialized with “drv_unload” by the DKIthread.

[0257] As already mentioned, in some cases, a driver may defer itsdevice initialization, until it is opened. This is a way to resolve aconflict about usage of the same resource by multiple drivers. In thatway, drivers sharing a resource can be loaded at same time, providedthey are not opened at same time. In such a case, the initialization andshutdown process of the driver has to be executed at runtime, i.e. attime of driver “open” and “close”, respectively, rather than as part ofthe kernel/drivers initialization process. Thus, deferred initializationdrivers should also use the above described DKI thread services toexplicitly synchronize with already running drivers.

[0258] On another hand, the relation between a bus driver and its childdriver(s) may offer several possibilities.

[0259] A bus driver may provide multiple API's. A typical example is aPCI bus driver providing a common bus API and a PCI bus API. The PCI busdriver API is named “pci” and specified by a “PciBusOps” structure. Thecommon bus driver API is named “bus” and specified by a “BusOps”structure, which provides a subset of services provided by “PciBusOps”.Such a bus driver is able to support drivers which use either common(“bus”) or PCI (“pci”) parent bus interface. When the bus driver invokesa child driver, it gives a pointer to either the “BusOps” or the“PciBusOps” structure depending on “bus_class” specified in the childdriver registry entry.

[0260] Conversely, a driver may be adaptive as to its parent bus API,i.e. be able to run on top of a number of different buses (e.g. “pci”and “is a”). Typically, such a driver is composed of two parts: busclass specific and bus class independent. The bus class specific part ofthe driver code mainly deals with the device probing and initialization.In addition, it provides an abstraction layer in order to hide the busclass dependencies from the bus class independent part of the drivercode.

[0261] Such a multi-bus driver should be registered multiple times inthe driver registry. Each entry specifies a given bus class API (via the“bus_class” field) on top of which the driver may run. In order todetermine to which bus class the driver is applied, the “drv_probe”,“drv_bind” and “drv_init” routines have to be entry specific (i.e. busclass API specific). Under such conditions, when a given driver'sroutine is invoked by a bus driver, the driver detects the bus class towhich it is applied and casts the “bus_ops” argument to the appropriatestructure (e.g. “PciBusOps”).

[0262] In this invention, as it will be appreciated, each driver hasdriver management functions and driver/device service functions. Inaccordance with the device tree (and the corresponding virtual drivertree), the functions are closely related to the needs of the driver todevice relation. This is advisable to avoid that shutdown of a driverinstance be detrimental to operation of other <device/driver instance>pairs.

[0263] Thus, the described system provides:

[0264] in operation, a simple tool for enabling driver client code toperform operations on a given device, using the device registry;

[0265] a flexible and consistent way of initializing drivers anddevices, when starting the computer;

[0266] a flexible and consistent way of taking new drivers into account,as well as to unload drivers, in operation;

[0267] a flexible and consistent way of managing device insertion and/orremoval (and/or failure), in operation;

[0268] a consistent way of managing resources shortage, whenappropriate.

[0269] These features may be used in any desired combination. In suchcombinations, the features being useless may be omitted.

[0270] This invention is not restricted to the embodiment as disclosed.Although it extensively refers to ChorusOS, it may be applied to otheroperating systems as well. The organization of the probing, binding andinitialization operations and loops may be different. The organizationof data and code may also be different; this remark concerns the driversand driver instances, the device registry, the driver registry, thedevice tree, and their relations. Also, despite the driver tree isdescribed as virtual, it may also be given a data representation.

What is claimed is:
 1. A computer comprising: a processor (110), amemory (115), and devices (118-138), a program memory area, for storingan operating system (205), drivers (218-238), and driver client code(250), each driver having a global driver section (6) comprising driverprogram code (60) and global driver data (61), both defining driveroperations associated with a corresponding class of devices, foroperative ones of the devices, an associated driver instantiation (71)comprising local driver data, having an internal pointer to the globaldriver section of the instantiated driver, the local driver data in atleast certain of the driver instantiations further having at least oneexternal pointer to another driver instantiation, a device registry(50), forming a list of device registry entries (711), eachcorresponding to a respective one of the driver instantiations, saiddriver client code (250) being capable of performing operations on agiven device by: fetching in said device registry (50) a pointer to thedriver instantiation (71) associated with the given device, performingthe operations on the given device by using operations provided by theassociated driver instantiation, directly or using further operationsreached in other driver instantiations by using iteratively saidexternal pointer.
 2. A computer according to claim 1, wherein said localdriver data further comprise local device data, defining a currentcondition of the device associated with the driver.
 3. A computeraccording to claim 1, further comprising device tree data (500-536),defining a tree representation of at least some of said devices, inwhich each device node represents a device and its devicecharacteristics, and identifies at most one driver capable of managingthat device.
 4. A computer according to claim 3, wherein said deviceregistry entry (711) further comprises a node identifier (715), definingan associated node in the device tree.
 5. A computer according to claim3, wherein said global driver section comprises code (60) adapted toimplement at least one of the following special operations: probingdriver serviceable devices, binding a driver serviceable device with thedriver, initializing a driver instantiation with the bound device,unloading an existing driver instantiation.
 6. A computer according toclaim 5, further comprising a driver registry (40), forming a list ofdriver registry entries, each comprising at least one pointer to saidspecial operations.
 7. A computer according to claim 6, wherein saiddriver registry (40) directly or indirectly defines device-independentdriver characteristics, comprising a driver identifier and a parentdriver class identifier.
 8. A computer according to claim 6, whereinsaid global driver section (6) comprises code adapted to self registerthe driver in said driver registry.
 9. A computer according to claim 6,wherein, for at least intermediary ones of the drivers, said specialoperation of initializing the driver further comprises sub-nodeinitialization operations (910-930).
 10. A computer according to claim9, wherein said sub-node initialization operations comprise inspectingthe driver registry to find child drivers which match the driver beingconsidered (913,923).
 11. A computer according to claim 10, wherein saidsub-node initialization operations comprise initiating a specialoperation of probing driver serviceable devices in such child drivers(918).
 12. A computer according to claim 6 or claim 11, wherein saidspecial operation of probing driver serviceable devices (918) comprisescreating corresponding device nodes in the device tree.
 13. A computeraccording to claim 12, wherein said sub-node initialization operationsfurther comprise allocating resources to each child driver serviceabledevice (919).
 14. A computer according to claim 12, wherein saidsub-node initialization operations further comprise binding a childdriver with a corresponding device in said device tree (920).
 15. Acomputer according to claim 14, wherein said sub-node initializationspecial operations further comprise initializing the child driver (930),which results into a nested implementation (940) of said sub-nodeinitialization operations when said child driver is itself anintermediate driver.
 16. A computer according to claim 5, wherein, forat least other drivers than the intermediary ones, said driver specialoperation of initializing a driver instantiation for the bound devicefurther comprises registering the new driver instantiation in the deviceregistry (998).
 17. A computer according to claim 5, wherein saidoperating system contains code for launching said sub-node operations ina driver bound to a given device in the device tree (207).
 18. Acomputer according to claim 17, wherein said code (207) for launchingsaid sub-node operations comprises a synchronizing thread in the nucleusof said operating system.
 19. A computer according to claim 17, whereinsaid operating system is active upon computer start to initiate saidcode (207) for launching said sub-node operations in a driver bound tothe main bus.
 20. A computer according to claim 17, wherein saidoperating system is active upon detection of a new driver to initiatesaid code (207) for launching said sub-node operations in a driver boundto the main bus.
 21. A computer according to claim 17, wherein saidoperating system is active, upon detection of a new device by anintermediate device, to initiate said code (207) for launching saidsub-node operations in the driver corresponding to the intermediatedevice.
 22. A computer according to claim 17, wherein said operatingsystem is arranged to de-activate the corresponding driverinstantiation, upon detection of a device removal.
 23. A method ofmanaging drivers in a computer, comprising: a. providing each driverwith a global driver section (6) comprising driver program code (60) andglobal driver data (61), both defining driver operations associated witha corresponding class of devices, b. for each operative one of thedevices, providing an associated driver instantiation (71) comprisinglocal driver data, having an internal pointer to the instantiateddriver, c. providing a device registry (50), forming a list of deviceregistry entries, each corresponding to a respective one of the driverinstantiations, whereby a device call may be directed to the deviceregistry, to reach the driver instantiation corresponding to the devicebeing called.
 24. The method of claim 23, wherein said local driver dataof step b. further comprise local device data, defining a currentcondition of the device associated with the driver.
 25. The method ofclaim 23, further comprising the step of: d. providing device tree data(500-536), defining a tree representation of at least some of saiddevices, in which each device node represents a device and its devicecharacteristics, and identifies at most one driver capable of managingthat device.
 26. The method of claim 25, wherein each said deviceregistry entry (711) of step c. further comprises a node identifier,defining an associated node in the device tree.
 27. The method of claim25, wherein said global driver section (6) of step a. further comprisescode adapted to implement at least one of the following specialoperations: a1. probing driver serviceable devices, a2. binding a driverserviceable device with the driver, a3. initializing a driverinstantiation with the bound device, a4. unloading an existing driverinstantiation.
 28. The method of claim 27, further comprising the stepof: e. providing a driver registry (40), forming a list of driverregistry entries, each comprising at least one pointer to said specialoperations.
 29. The method of claim 28, wherein said driver registry(40) of step e. directly or indirectly defines device-independent drivercharacteristics, comprising a driver identifier and a parent driverclass identifier.
 30. The method of claim 29, wherein said global driversection (6) of step a. comprises code adapted to self register thedriver in said driver registry.
 31. The method of claim 29, wherein, forat least intermediary ones of the drivers, said special operation al. ofinitializing the driver further comprises sub-node initializationoperations (910-930).
 32. The method of claim 31, wherein said sub-nodeinitialization operations comprise: a10. inspecting the driver registryto find child drivers which match the driver being considered (913,923).33. The method of claim 32, wherein said sub-node initializationoperations comprise a11. initiating a special operation of probingdriver serviceable devices in such child drivers (910).
 34. The methodof claim 27 or claim 32, wherein said special operation of probingdriver serviceable devices further comprises creating correspondingdevice nodes in the device tree (918).
 35. The method of claim 34,wherein said sub-node initialization operations further comprisedefining resources requirements for each child driver serviceable device(918).
 36. The method of claim 35, wherein said sub-node initializationoperations further comprise: a12. binding a child driver with acorresponding device in said device tree (920).
 37. The method of claim36, wherein said sub-node initialization special operations furthercomprise: a13. initializing the child driver (930), which results into anested implementation (940) of said sub-node initialization operationswhen said child driver is itself an intermediate driver.
 38. The methodof claim 27, wherein, for at least other drivers than the intermediaryones, said driver special operation of initializing a driverinstantiation for the bound device further comprises registering the newdriver instantiation in the device registry (998).
 39. The method ofclaim 31, further comprising the step of: f. providing the operatingsystem of the computer with code (207) for launching said sub-nodeoperations in a driver bound to a given device in the device tree. 40.The method of claim 39, wherein said code (207) for launching saidsub-node operations of step f. comprises a synchronizing thread in thenucleus of said operating system.
 41. The method of claim 39, whereinstep f. is implemented upon computer start with a driver bound to themain bus.
 42. The method of claim 39, wherein step f. is implementedduring computer operation, upon detection of a new driver, with a driverbound to the main bus.
 43. The method of claim 39, wherein step f. isimplemented during computer operation, upon detection of a new device byan intermediate device, with the driver corresponding to theintermediate device.
 44. The method of claim 39, further comprising thestep of: g. providing the operating system of the computer with code(207) operable upon detection of a device removal to launchde-activation of the corresponding driver instantiation.
 45. A driver,having a global driver section (6) comprising driver program code (60)and global driver data (61), both defining driver operations associatedwith a corresponding class of devices, and a driver initializationoperation enabling the construction of driver instantiations comprisinglocal driver data, having an internal pointer to the instantiateddriver.
 46. A driver according to claim 45, wherein said local driverdata further comprises a driver registry entry (711).
 47. A driveraccording to claim 45, wherein said global driver section (6) furtherdefines an operation of self-registration in a driver register.
 48. Adriver according to claim 45, wherein said global driver section (6)further defines an operation of probing driver serviceable devices. 49.An operating system, having device and driver management code, whereinsaid device and driver management code (207) comprises a dedicatedsynchronizing thread, code for tree management, code for managing adriver registry, code for managing a device registry, and code forlaunching selected operations in a designated driver.
 50. The operatingsystem of claim 49, wherein the designated driver is the main busdriver.